package com.asa.ui.H;

public class Board {

	public static char EMPTY='.';
	
	private int N,M;
	private char[][] data;
	
	private Board preBoard;
	private String swapString = "";
	
	
	public Board(String[] lines) {
		
		if (lines==null) {
			throw new IllegalArgumentException("lines cannot be null");
		}
		N = lines.length;
		if (N==0) {
			throw new IllegalArgumentException("lines.length cannot be 0");
		}
		
		M = lines[0].length();
		data = new char[N][M];
		for (int i = 0; i < N; i++) {
			if (lines[i].length() !=M) {
				throw new IllegalArgumentException("all lines.length must be same");
			}
			for (int j = 0; j < M; j++) {
				data[i][j] = lines[i].charAt(j);
			}
		}
		
		
		
	}
	public Board(Board starterBoard,Board preBoard,String swapString) {
		// TODO Auto-generated constructor stub
		if (starterBoard==null) {
			throw new IllegalArgumentException("starterBoard cannot be null");
		}
		this.N = starterBoard.getN();
		this.M = starterBoard.getM();

		this.data = new char[N][M];
		
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				this.data[i][j] = starterBoard.data[i][j];
			}
		}
		this.preBoard = preBoard;
		this.swapString = swapString;
		
	}
	
	public Board(Board board) {
		// TODO Auto-generated constructor stub
		this(board,null,"");
	}
	
	

	
	
	public int getN() {
		return N;
	}
	public int getM() {
		return M;
	}
	
	public boolean inArea(int x,int y) {
		return x>=0 && x<N && y>=0 && y<M;
	}
	
	public char getData(int x,int y) {
		if (!inArea(x,y)) {
			throw new IllegalArgumentException("x,y are out of index in getData");
		}
		
		return data[x][y];
	}
	public void print() {
		for (int i = 0; i < N; i++) {
			System.out.println(String.valueOf(data[i]));
		}
	}
	public boolean isWin() {
		// TODO Auto-generated method stub
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				if (data[i][j]!=EMPTY) {
					return false;
				}
			}
		}
		
		printSwapInfo();
		
		
		return true;
	}
	
	
	public void printSwapInfo() {
		// TODO Auto-generated method stub
		if (preBoard!=null) {
			preBoard.printSwapInfo();
		}
		System.out.println(swapString);
	}
	
	
	
	public void swap(int x, int y, int newX, int newY) {
		// TODO Auto-generated method stub
		if (!inArea(x,y)||!inArea(newX,newY)) {
			throw new IllegalArgumentException("x,y,newX,newY are out of index in getData");
		}
		
		char c = this.data[x][y];
		this.data[x][y] = this.data[newX][newY];
		this.data[newX][newY]=c;
		
		
	}
	public void run() {
		// TODO Auto-generated method stub
		do {
			drop();
		}while(match());
		
		
		return;
		
		
	}
	private static int d[][] = {{0,1},{1,0}};
	private boolean match() {
		// TODO Auto-generated method stub
		boolean isMatched = false;
		boolean tag[][] = new boolean[N][M];
		for (int x = 0; x < N; x++) {
			for (int y = 0; y < M; y++) {
				
				if (data[x][y]!= EMPTY) {
					for (int i = 0; i < 2; i++) {
						int newX1 = x+d[i][0];
						int newY1 = y +d[i][1];
						int newX2 = newX1+d[i][0];
						int newY2 = newY1 +d[i][1];
						if (inArea(newX1, newY1)&&inArea(newX2, newY2)&&
								data[newX1][newY1] == data[x][y]&&
								data[newX2][newY2] == data[x][y]) {
							tag[x][y] = true;
							tag[newX1][newY1] = true;
							tag[newX2][newY2] = true;

						}
						
						
					}
				}
				
			}
			
			
		}
		
		for (int x = 0; x < N; x++) {
			for (int y = 0; y < M; y++) {
				if (tag[x][y]) {
					data[x][y] = EMPTY;
					isMatched = true;
				}
				
			}
		}
		
		
		
		
		
		
		
		return isMatched;
	}
	private void drop() {
		// TODO Auto-generated method stub
		for (int j = 0; j < M; j++) {
			int cur = N-1;
			for (int i = N-1; i >0; i--) {
				if (data[i][j] !=EMPTY) {
					swap(i, j, cur, j);
					cur--;
				}
				
			}
			
		}
		
		
	}
	
	
	
}
